package br.uece.tcc.flathead.jxta;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import net.jxta.credential.AuthenticationCredential;
import net.jxta.credential.Credential;
import net.jxta.discovery.DiscoveryService;
import net.jxta.document.AdvertisementFactory;
import net.jxta.document.MimeMediaType;
import net.jxta.document.StructuredDocument;
import net.jxta.exception.PeerGroupException;
import net.jxta.exception.ProtocolNotSupportedException;
import net.jxta.membership.Authenticator;
import net.jxta.membership.MembershipService;
import net.jxta.peergroup.PeerGroup;
import net.jxta.peergroup.PeerGroupFactory;
import net.jxta.protocol.ModuleImplAdvertisement;
import net.jxta.protocol.PeerGroupAdvertisement;

/*
 * PeerGroupManager
 * Created on 11/06/2005
 *
 *
 */

/**
 * @author edward ribeiro
 * 
 */
public class PeerGroupManager {
	
	private static PeerGroup parentGroup = null;
	private static PeerGroup childGroup = null;
	
	public PeerGroupManager() throws Exception {		
		parentGroup = PeerGroupFactory.newNetPeerGroup();				
		childGroup = loadGroup("group.adv", parentGroup);	
		joinGroup(childGroup);		
		startGroup();			
	}
	
	/** Search for peers in the group */
	public void startGroup() throws InterruptedException {
		
		DiscoveryService ds = childGroup.getDiscoveryService();								
		while (true) {
			ds.getRemoteAdvertisements(null, DiscoveryService.PEER, null, null, 0);
			Thread.sleep(5000);
		}			
	}
	
	/** Initialize a group Advertisement from a file */
	public static PeerGroup loadGroup(String filename, PeerGroup parent) throws IOException, PeerGroupException {
		PeerGroupAdvertisement padv = loadAdv(filename);
		PeerGroup group = parent.newGroup(padv);
		return group;
	}
	
	/** Create a group Advertisement */
	public static PeerGroup createGroup(PeerGroup parent, String name) throws Exception {
		ModuleImplAdvertisement implAdv = parent.getAllPurposePeerGroupImplAdvertisement();		
		PeerGroup group = parent.newGroup(null, implAdv, name, name);
		return group;
	}
	
	/** Create a group and save it to a file */
	public static void createAndSave(PeerGroup parent, String filename) throws Exception {		
		PeerGroup child = createGroup(parent, filename);
		saveAdv(filename, child.getPeerGroupAdvertisement());			
	}
	
	/** Join a group */
	public static void joinGroup(PeerGroup childGroup) throws PeerGroupException, ProtocolNotSupportedException {
		
		StructuredDocument creds = null;
		AuthenticationCredential authCred = new AuthenticationCredential(childGroup, null, creds);
		MembershipService membership = childGroup.getMembershipService();
		Authenticator auth = membership.apply(authCred);
		if (auth.isReadyForJoin()) {
			Credential myCred = membership.join(auth);
			childGroup.getRendezVousService().setAutoStart(true, 30000);	
		}
	}
	
	/** Load a PeerGroup Advertisement from a file */
	public static PeerGroupAdvertisement loadAdv(String filename) throws IOException {		
		PeerGroupAdvertisement padv = null;		
		FileInputStream fis = new FileInputStream(filename);
		padv = (PeerGroupAdvertisement) AdvertisementFactory.newAdvertisement(MimeMediaType.XMLUTF8,fis);			
		return padv;
	}
	
	/** Save a PeerGroup Advertisement to a file */
	public static void saveAdv(String filename, PeerGroupAdvertisement padv) throws IOException {			
		FileOutputStream fos = new FileOutputStream(filename);		
		fos.write(padv.toString().getBytes());		
		fos.flush();
		fos.close();		
	}
}
